/*
 * DatagramBuilder Library: serialize/deserialize data to/from datagram
 * Copyright (C) 2008 Rakov Ilya <RakovIlya@gmail.com>
 *
 * This library can be distributed under the terms of the GNU LGPLv2.
 * See the file COPYING.LIB.
 */


#ifndef DATAGRAM_PARSER_H_
#define DATAGRAM_PARSER_H_


/**
 * @file Parser.h
 *
 * @brief Parser header file
 *
 * @date Dec 4, 2008
 * @author Rakov Ilya
 */


#include "Container.h"
#include "Tag.h"

#include <ostream>
#include <string>


/**
 * @brief This class provides an ability to deserialize data.
 */
class Parser
{

public: // user interface


  class ScopedTransaction;


  /**
   * @brief ctor
   * @param container Data source
   */
  Parser( const Container &container );

  /**
   * @return Flag whether we have treated Parser.
   */
  inline bool IsTreated() const;


  /**
   * @return Size of the already treated data.
   */
  inline size_t GetTreated() const;


  /**
   * @return Container size
   */
  inline size_t GetSize() const;


  /**
   * @brief Provides an ability to output the Parser's state into an output streams.
   * @param out Output stream
   */
  template< class CharType, class CharTrait >
  inline void ToStream( std::basic_ostream< CharType, CharTrait > &out ) const;


/**@{ @name Deserialization interface */

  /**
   * @brief Common way to check data consistency.
   *
   * Result of the data deserialization compares with sample value.
   * On equality nothing happens or else the deserialization_error throws.
   *
   * @param value The Data sample
   * @return The same parser
   * @exception deserialization_error
   * @note Provides exception-safety.
   */
  template < class T >
  inline Parser& operator >>( const T &value );


  /**
   * @brief Common way to deserialize data.
   *
   * @param value Data to deserialize
   * @return The same parser
   * @exception deserialization_error
   * @note Provides exception-safety.
   */
  template < class T >
  inline Parser& operator >>( T &value );


  /**
   * @brief Common way to deserialize tagged data.
   *
   * @param value Data to deserialize
   * @return The same parser
   * @exception deserialization_error
   * @note Provides exception-safety.
   */
  template < class T >
  inline Parser& operator >>( Tag< T > value );

/**@}*/

/**@{ @name Raw deserialization interface */

  /**
   * @brief Deserializes fixed-size values.
   *
   * The value gets by offset.
   * @param value Value
   * @exception deserialization_error
   */
  template< class T >
  inline void DeSerializeValue( T &value );


  /**
   * @brief Deserializes variable values.
   *
   * SIZE_T is a data type of the variable data size.
   * @param inserter Value inserter
   * @exception deserialization_error
   */
  template< class SIZE_T, class T >
  inline void DeSerializeValue( std::back_insert_iterator<T> inserter );

/**@}*/


private:  // implementation

  template< class T > friend class Mark;
  template< class T > inline void DeSerializeValue( T &value, size_t offset ) const;


private:  // implementation

  Container container_;
  size_t    transactNext_;
  size_t    commitedNext_;

};


/** @relates Parser
 *
 * @brief Provides an ability to output the Parser's state into an output streams.
 *
 * @param out Output stream
 * @param obj Parser
 */
template< class CharType, class CharTrait >
inline std::basic_ostream< CharType, CharTrait >&
operator <<( std::basic_ostream<CharType, CharTrait> &out, const Parser &obj );


#include "impl/ParserImpl.h"



#endif /* DATAGRAM_PARSER_H_ */
